package io.shdxhl.simplerpc.code.netty.handler;

import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.shdxhl.simplerpc.code.bean.SimpleBeanFactory;
import io.shdxhl.simplerpc.code.netty.request.RpcRequest;
import io.shdxhl.simplerpc.code.netty.response.RpcResponse;
import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

@Slf4j
@ChannelHandler.Sharable
public class RpcRequestHandler extends SimpleChannelInboundHandler<RpcRequest> {
    @Override
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, RpcRequest rpcRequest) throws Exception {
        log.info("RpcRequestHandler 收到请求为:{}", rpcRequest);
        RpcResponse rpcResponse = new RpcResponse();
        rpcResponse.setRequestId(rpcRequest.getRequestId());
        String interfaceName = rpcRequest.getClassName();
        String methodName = rpcRequest.getMethodName();
        Class<?>[] parameterTypes = rpcRequest.getParameterTypes();
        Object[] parameters = rpcRequest.getParameters();

        //获取当前bean对象
        try {
            Object bean = SimpleBeanFactory.getBean(Class.forName(interfaceName));
            Method method = bean.getClass().getMethod(methodName, parameterTypes);
            Object result = method.invoke(bean, parameters);
            rpcResponse.setResult(result);
        } catch (Throwable e) {
            rpcResponse.setCause(e);
            log.error("RpcRequestHandler 执行接口方法失败，msg={}",e.getMessage());
        }finally {
            //RpcResponse写回去
            channelHandlerContext.writeAndFlush(rpcResponse);
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        log.error("RpcRequestHandler 服务端解析异常，msg:{}", cause.getMessage());
        super.exceptionCaught(ctx, cause);
    }
}
